package com.gzhryc.dictionary.services;

import com.gzhryc.common.ClassTools;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.dictionary.dao.ConfigInfoDao;
import com.gzhryc.dictionary.dao.db.ConfigInfo;
import com.gzhryc.dictionary.dao.enums.ConfigInfoEnum;
import com.gzhryc.jdbc.Conditions;
import com.gzhryc.jdbc.JdbcSession;
import com.gzhryc.jdbc.MultiDBTools;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;

/**
 * 类型数据业务处理类
 * @author 张浩
 * @version 2016-11-13
 */
public class ConfigInfoService {

	static Logger log = Logger.getLogger(ConfigInfoService.class);

	public static ConfigInfoService self() {
		return MultiDBTools.getService(ConfigInfoService.class, true);
	}

	public static ConfigInfoService self(String jdbcKey) {
		return MultiDBTools.getService(jdbcKey, ConfigInfoService.class, true);
	}

	ConfigInfoDao dao;

	public ConfigInfoService(String jdbcKey) {
		this.dao = new ConfigInfoDao(jdbcKey);
	}

	public ConfigInfo getByTypeAndName(Integer type, String name) {
		if (type != null && StringUtils.isNotBlank(name)) {
			Conditions condition = new Conditions(ConfigInfo.class);
			condition.and().is("type", type);
			condition.and().is("name", name);
			try {
				return dao.get(condition);
			} catch (SQLException e) {
				log.error(e.getMessage(), e);
			}
		}
		return null;
	}

	public List<ConfigInfo> findByType(Integer type) {
		if (type != null) {
			Conditions condition = new Conditions(ConfigInfo.class);
			condition.and().is("type", type);
			try {
				return dao.findByCondition(condition);
			} catch (SQLException e) {
				log.error(e.getMessage(), e);
			}
		}
		return null;
	}

	private boolean save(Integer type, String name, Class<?> dataClass, Object value,boolean isCreate) {
		if (type != null && StringUtils.isNotBlank(name) && dataClass != null && value != null) {
			ConfigInfo config = new ConfigInfo();
			if (Integer.class.equals(dataClass) || int.class.equals(dataClass)) {
				config.setDataType(ConfigInfoEnum.DataType.IntegerType.index());
				config.setIntegerValue(ClassTools.toType(Integer.class, value));
			} else if (Long.class.equals(dataClass) || long.class.equals(dataClass)) {
				config.setDataType(ConfigInfoEnum.DataType.LongType.index());
				config.setLongValue(ClassTools.toType(Long.class, value));
			} else if (Double.class.equals(dataClass) || double.class.equals(dataClass)) {
				config.setDataType(ConfigInfoEnum.DataType.DoubleType.index());
				config.setDoubleValue(ClassTools.toType(Double.class, value));
			} else if (Date.class.equals(dataClass)) {
				config.setDataType(ConfigInfoEnum.DataType.DateType.index());
				config.setDateValue(ClassTools.toType(Date.class, value));
			} else if (Boolean.class.equals(dataClass)) {
				config.setDataType(ConfigInfoEnum.DataType.BooleanType.index());
				config.setBooleanValue(ClassTools.toType(Boolean.class, value));
			} else {
				config.setDataType(ConfigInfoEnum.DataType.StringType.index());
				config.setStringValue(ClassTools.toType(String.class, value));
			}

			if(isCreate){
				config.setType(type);
				config.setName(name);
				config.setCreateDate(new Date());
				try {
					return dao.insert(config) > 0;
				} catch (SQLException e) {
					log.error(e.getMessage(), e);
				}
			}else{
				Conditions condition = new Conditions(ConfigInfo.class);
				condition.and().is("type", type);
				condition.and().is("name", name);
				try {
					return dao.updateNotNull(config, condition) > 0;
				} catch (SQLException e) {
					log.error(e.getMessage(), e);
				}
			}
		}
		return false;
	}

	private boolean del(Integer type, String name) {
		if(type != null && StringUtils.isNotBlank(name)) {
			Conditions condition = new Conditions(ConfigInfo.class);
			condition.and().is("type", type);
			condition.and().is("name", name);
			try {
				return dao.deleteByCondition(condition) > 0;
			} catch (SQLException e) {
				log.error(e.getMessage(), e);
			}
		}
		return false;
	}

	/**
	 * 获取参数
	 *
	 * @param type
	 * @param clazz
	 * @return
	 */
	public <T> T getConfig(Integer type, Class<T> clazz) {
		List<ConfigInfo> configList = findByType(type);
		if (configList != null && configList.size() > 0) {
			try {
				T result = clazz.newInstance();
				Field[] fields = ClassTools.getDeclaredFields(clazz);
				for (Field field : fields) {
					if (!Modifier.isFinal(field.getModifiers())) {
						field.setAccessible(true);
						for (ConfigInfo config : configList) {
							if (field.getName().equals(config.getName())) {
								try {
									field.set(result, config.getValue());
								} catch (IllegalArgumentException e) {
									log.error(e.getMessage(), e);
								} catch (IllegalAccessException e) {
									log.error(e.getMessage(), e);
								}
								break;
							}
						}
					}
				}
				return result;
			} catch (InstantiationException e1) {
				e1.printStackTrace();
			} catch (IllegalAccessException e1) {
				e1.printStackTrace();
			}
		}
		return null;
	}

	/**
	 * 保存参数
	 *
	 * @param type
	 * @param config
	 * @return
	 */
	public <T> boolean save(Integer type, T config) {
		Field[] fields = ClassTools.getDeclaredFields(config.getClass());

		List<ConfigInfo> configInfoList = this.findByType(type);

		boolean flag = true;
		JdbcSession.begin();
		try {
			for (Field field : fields) {
				if (!Modifier.isFinal(field.getModifiers())) {
					field.setAccessible(true);
					int index = -1;
					boolean isCreate = true;
					if(configInfoList != null && configInfoList.size() > 0) {
						for (int i =0;i < configInfoList.size();i++) {
							ConfigInfo configInfo = configInfoList.get(i);
							if(configInfo.getName().equals(field.getName())){
								index = i;
								break;
							}
						}
						if(index > -1){
							isCreate = false;
							configInfoList.remove(index);
						}
					}
					Object obj = field.get(config);
					if (obj != null) {
						flag = flag && save(type, field.getName(), field.getType(), obj, isCreate);
					} else if(!isCreate){
						del(type, field.getName());
					}
					if (!flag) {
						break;
					}
				}
			}
			if (flag) {
				//删除已经不存在的参数
				if(configInfoList != null && configInfoList.size() > 0){
					for(ConfigInfo configInfo : configInfoList){
						del(type, configInfo.getName());
					}
				}
				JdbcSession.commit();
				return true;
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		} finally {
			JdbcSession.end();
		}
		return false;
	}
}
